//
//  RSNumber.h
//  RSMath
//
//  Copyright (c) 2007-2009 Raphael Sobik. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//  1. Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//  3. The name of the author may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY Raphael Sobik "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
//  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
//  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

// This class is mainly a wrapper around the OpensSSL bn library.
// The methods never modify themselfes but return a new object containig the result

#import <Foundation/Foundation.h>
#import <openssl/bn.h>

@interface RSNumber : NSObject <NSCoding, NSCopying>
{
	BIGNUM *bignum;
	BN_CTX *ctx;
}

@property(readonly) BIGNUM *bignum;
@property(readonly) NSString *string;
@property(readonly) NSString *description;

- (id)init;
- (id)initWithInteger:(NSInteger)integer;
- (id)initWithUnsignedInteger:(NSUInteger)integer;
- (id)initWithString:(NSString *)string;

- (id)copyWithZone:(NSZone *)zone;
//-(RSNumber *)copy;

- (void)dealloc;
- (void)finalize;

+ (id)numberWithInteger:(NSInteger)integer;
+ (id)numberWithUnsignedInteger:(NSUInteger)integer;
+ (id)numberWithString:(NSString *)string;
+ (id)number;

- (id)initWithCoder:(NSCoder *)encoder;
- (void)encodeWithCoder:(NSCoder *)encoder;

- (BOOL)isZero;
- (BOOL)isOne;
- (BOOL)isNegative;
- (BOOL)isLargerThan:(RSNumber *)number;
- (BOOL)isEqualToNumber:(RSNumber *)number;
- (BOOL)isSmallerThan:(RSNumber *)number;

- (BOOL)isPrime;
- (NSArray *)factorization;

- (RSNumber *)mod:(RSNumber *)mod;

- (RSNumber *)inverseMod:(RSNumber *)mod;

- (RSNumber *)add:(RSNumber *)otherNumber;
- (RSNumber *)add:(RSNumber *)otherNumber mod:(RSNumber *)mod;

- (RSNumber *)subtract:(RSNumber *) otherNumber;
- (RSNumber *)subtract:(RSNumber *) otherNumber mod:(RSNumber *)mod;

- (RSNumber *)multiplyWith:(RSNumber *) otherNumber;
- (RSNumber *)multiplyWith:(RSNumber *) otherNumber mod:(RSNumber *)mod;

- (RSNumber *)divideWith:(RSNumber *) otherNumber;

- (RSNumber *)toThePowerOf:(RSNumber *) otherNumber;
- (RSNumber *)toThePowerOf:(RSNumber *) otherNumber mod:(RSNumber *)mod;

@end
